<?php
/**
 * BRoute.php
 *
 * @author Chen HuiYun <11chenhuiyun@gmail.com>
 * @copyright Copyright &copy; 2012-2020 MyyTaijii Software LLC
 */

/**
 * 路由器管理类
 * @author Chen HuiYun
 */
class BRoute
{
	//
	private $_tempType;
	private $_tempRule;
	private $_tempAction;
	private $_tempMainObj;
	private $_tempSubObj;
	//
	private $_nowType;
	private $_nowRule;
	private $_nowAction;
	private $_nowMainObj;
	private $_nowSubObj;
	/**
	 * @var BRouteBeanArray
	 */
	private $_routeBean;
	private $_errorBean;
	/**
	 * @var BHttpRequest
	 */
	private $_request;
	//
	private $_routeMappingCacheKey = 'cache_routemapping';
	/**
	 * TODO
	 */
	private $_strroutexml = null;
	//
	private $_routeRollback = false;
	
	public function __construct($config=null)
	{
		$this->_request = new BHttpRequest();
		
		if(is_string($config))
			$config=require($config);
		
		Ji::setPathOfAlias('webroot', dirname($_SERVER['SCRIPT_FILENAME']));

		$this->configure($config);
	}
	
	protected function configure($config)
	{
		//TODO 改为魔术方法
		foreach ($config as $key => $value) {
			if ($key == 'import') {
				$this->setImport($value);
			}
		}
	}
	
	public function setImport($aliases)
	{
		foreach($aliases as $alias) {
			Ji::import($alias);
		}
	}
	
	public function run()
	{
	    $this->setRouteParamsFromPage();
	
	    $this->createRouteBean();
	
	    $this->refreshRouteParams();
	
	    if (!$this->_tempMainObj) {
	    	$this->runWeb();
	    }
	    else
	    {
	    	$this->detectError();
	    	$this->refreshRouteParam();
	    	$this->runBusiness();
	    }
	
	    if (0) {
	    	return;
	    }
	    $this->_request->setRequestValue('routeBean', $this->_routeBean);
	
	    $target = $this->getTarget();
	    BLog::info($this, 'target: '.$target);
	    BLog::error($this, 'error');
	    if ($this->_routeBean->getType('0') == BRouteBean::TYPE_PRE) {
	    	$this->_routeBean->setType('0', BRouteBean::TYPE_DSP);
	    }
	    else if ($this->_routeBean->getType('0') == BRouteBean::TYPE_ACT) {
	    	$this->_routeBean->setType('0', BRouteBean::TYPE_PRE);
	    }
	    
	    if (preg_match("/^.*\.php$/", '.php') === 1)
	    {
	    	$this->_routeBean->setType('0', BRouteBean::TYPE_PRE);
	    	$this->render($target, $this->_request);
	    	return;
	    }
	    
	    //$errMsgBean = new ErrorMessageBean();
	    $action = null;
	    try {
	    	$action = new $target();
	    } 
	    catch (Exception $e) {
	      BLog::error($this, $e->getMessage());
	      throw new Exception('不能创建Action类：' .$e->getMessage());
	      //$errMsgBean->addCommonMessage('不能创建Action类：' .$e->getMessage());
	    }
	    $action->run($this->_request);
	    
	    $this->run();
	}
	
	private function setRouteParamsFromPage()
	{
	    $this->_tempType = trim($this->_request->getRequestValue("temptype"));
	    $this->_tempAction = trim($this->_request->getRequestValue("tempaction"));
	    $this->_tempRule = trim($this->_request->getRequestValue("temprule"));
	    $this->_tempMainObj = trim($this->_request->getRequestValue("tempmainobj"));
	    $this->_tempSubObj = trim($this->_request->getRequestValue("tempsubobj"));
	    
	    BLog::info($this, '###################################');
	    BLog::info($this, 'tempType: ' .$this->_tempType);
	    BLog::info($this, 'tempAction: ' .$this->_tempAction);
	    BLog::info($this, 'tempRule: ' .$this->_tempRule);
	    BLog::info($this, 'tempMainObj: ' .$this->_tempMainObj);
	    BLog::info($this, 'tempSubObj: ' .$this->_tempSubObj);
	    BLog::info($this, '###################################');
	}
	
	private function createRouteBean()
	{
		$routeBean = $this->_request->getRequestValue('routeBean');
		$this->_routeBean = $routeBean ? $routeBean : new BRouteBeanArray();
	}
	
	private function refreshRouteParams()
	{
		$this->_nowType = $this->_routeBean->getType(0);
	    $this->_nowAction = $this->_routeBean->getAction(0);
	    $this->_nowRule = $this->_routeBean->getRule(0);
	    $this->_nowMainObj = $this->_routeBean->getMainObj(0);
	    $this->_nowSubObj = $this->_routeBean->getSubObj(0);
	    
	    BLog::info($this, '###################################');
	    BLog::info($this, 'nowType: ' .$this->_nowType);
	    BLog::info($this, 'nowAction: ' .$this->_nowAction);
	    BLog::info($this, 'nowRule: ' .$this->_nowRule);
	    BLog::info($this, 'nowMainObj: ' .$this->_nowMainObj);
	    BLog::info($this, 'nowSubObj: ' .$this->_nowSubObj);
	    BLog::info($this, '###################################');
	}
	
	private function runWeb()
	{
		$index1 = 0;
		$index2 = 0;
		$total = 0;
		
		$tempRule = $this->_tempRule;
		$forwardRules = array('forward', 'act-again');
		$keepnoneRules = array(
			'keepnone', 'act-back', 'act-view', 'act-new', 'act-home', 
			'act-close', 'act-closeparent', 'act-redirect', 'act-spec'
		);
		$keepdataRules = array('keepdata');
		$keepallRules = array('keepall');
		$cancelRules = array('cancel');
		$backwardRules = array('backward');
		if (in_array($tempRule, $forwardRules)) {
			$this->_routeBean->unshiftItem();
			$this->_routeBean->setData(0, '');
			$this->_routeBean->setType(0, $this->_tempType);
			$this->_routeBean->setAction(0, $this->_tempAction);
			$this->_routeBean->setRule(0, $this->_tempRule);
			$this->_routeBean->setMainObj(0, $this->_tempMainObj);
			$this->_routeBean->setSubObj(0, $this->_tempSubObj);
			
			$this->_request->setRequestValue('temptype', '');
			$this->_request->setRequestValue('tempaction', '');
			$this->_request->setRequestValue('temprule', '');
			$this->_request->setRequestValue('tempmainobj', '');
			$this->_request->setRequestValue('tempsubobj', '');
		}
		else if (in_array($tempRule, $keepnoneRules)) {
			$this->_routeBean->setData(0, '');
			$this->_routeBean->setType(0, $this->_tempType);
			$this->_routeBean->setAction(0, $this->_tempAction);
			$this->_routeBean->setRule(0, $this->_tempRule);
			$this->_routeBean->setMainObj(0, $this->_tempMainObj);
			$this->_routeBean->setSubObj(0, $this->_tempSubObj);
			
			$this->_request->setRequestValue('temptype', '');
			$this->_request->setRequestValue('tempaction', '');
			$this->_request->setRequestValue('temprule', '');
			$this->_request->setRequestValue('tempmainobj', '');
			$this->_request->setRequestValue('tempsubobj', '');
		}
		else if (in_array($tempRule, $keepdataRules)) {
			$this->_routeBean->setType(0, $this->_tempType);
			$this->_routeBean->setAction(0, $this->_tempAction);
			$this->_routeBean->setRule(0, $this->_tempRule);
			$this->_routeBean->setMainObj(0, $this->_tempMainObj);
			$this->_routeBean->setSubObj(0, $this->_tempSubObj);
			
			$this->_request->setRequestValue('temptype', '');
			$this->_request->setRequestValue('tempaction', '');
			$this->_request->setRequestValue('temprule', '');
			$this->_request->setRequestValue('tempmainobj', '');
			$this->_request->setRequestValue('tempsubobj', '');
		}
		else if (in_array($tempRule, $keepallRules)) {
			$this->_routeBean->setRule(0, 'backward');
			
			$this->_request->setRequestValue('temptype', '');
			$this->_request->setRequestValue('tempaction', '');
			$this->_request->setRequestValue('temprule', '');
			$this->_request->setRequestValue('tempmainobj', '');
			$this->_request->setRequestValue('tempsubobj', '');
		}
		else if (in_array($tempRule, $cancelRules)) {
			if ($this->_routeBean->size() > 0) {
				$this->_routeBean->shiftItem();
				$this->_routeBean->setRule(0, 'backward');
			}
			
			$this->_request->setRequestValue('temptype', '');
			$this->_request->setRequestValue('tempaction', '');
			$this->_request->setRequestValue('temprule', '');
			$this->_request->setRequestValue('tempmainobj', '');
			$this->_request->setRequestValue('tempsubobj', '');
		}
		else if (in_array($tempRule, $backwardRules)) {
			$this->_routeBean->setType(0, $this->_tempType);
			$this->_routeBean->setAction(0, $this->_tempAction);
			$this->_routeBean->setRule(0, $this->_tempRule);
			
			$this->_request->setRequestValue('temptype', '');
			$this->_request->setRequestValue('tempaction', '');
			$this->_request->setRequestValue('temprule', '');
		}
	}
	
	private function detectError()
	{
		//TODO
	}
	
	private function runBusiness()
	{
		//TODO
	}

	private function getTarget() 
	{return null;
		$mainObj = $this->_routeBean->getMainObj(0);
	    $subObj = $this->_routeBean->getSubObj(0);
	    $type = $this->_routeBean->getType(0);
	    $action = $this->_routeBean->getAction(0);
	    
	    $this->routeBean2Requeset();
	    $pmainobj = $this->_request->setRequestValue("pmainobj");
	    $paction = $this->_request->setRequestValue("paction");
	    $psubobj = $this->_request->setRequestValue("psubobj");
	    //TODO
	    $userName = $this->_request->setRequestValue("userid");
	    
	    $routeKeyMain = $type . "_" . $action . $mainObj . "?";
	    $routeKey = $type . "_" . $action . $mainObj . $subObj;
	    
	    $routeCache = CommonObjectCache::get($this->_routeMappingKey);
	    if (!$routeCache) {
	    	$routeCache = $this->parseRouteMapping();
	    	CommonObjectCache::put($this->_routeMappingKey, $routeCache);
	    }
	    
	    $target = $routeCache->get($routeKey);
	    if (!$target) {
	    	Log::info($this, "路由Key：" . $routeKeyMain);
	    	$target = $routeCache->get($routeKeyMain);
	    } 
	    else {
	    	Log::info($this, "路由Key：" . $routeKey);
	    }
	
	    if (!$target)
	    {
	    	if ($routeKey == '_') {
	    		$target = "/index.php";
	    	}
	    	else {
	    		$target = "/common/php/error.php";
	        	$this->_request->setRequestValue("errorcommonmessage", "没有对应的路由信息：" . $routeKey);
	    	}
	    }
	    
	    return $target;
	}
	
	private function routeBean2Requeset()
	{
		$this->_request->setRequestValue('pmainobj', $this->_routeBean->getMainObj(0));
		$this->_request->setRequestValue('psubobj', $this->_routeBean->getSubObj(0));
		$this->_request->setRequestValue('paction', $this->_routeBean->getAction(0));
		$this->_request->setRequestValue('pdata', $this->_routeBean->getData(0));
	}
	
	private function render($target, $request) 
	{
		print_r($request);
	}
}
